home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / djgpp / src / binutils.252 / gas / symbols.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-12  |  36.9 KB  |  1,507 lines

  1. /* symbols.c -symbol table-
  2.    Copyright (C) 1987, 1990, 1991, 1992, 1993, 1994
  3.    Free Software Foundation, Inc.
  4.  
  5.    This file is part of GAS, the GNU Assembler.
  6.  
  7.    GAS is free software; you can redistribute it and/or modify
  8.    it under the terms of the GNU General Public License as published by
  9.    the Free Software Foundation; either version 2, or (at your option)
  10.    any later version.
  11.  
  12.    GAS is distributed in the hope that it will be useful,
  13.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.    GNU General Public License for more details.
  16.  
  17.    You should have received a copy of the GNU General Public License
  18.    along with GAS; see the file COPYING.  If not, write to
  19.    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  20.  
  21. /* #define DEBUG_SYMS / * to debug symbol list maintenance */
  22.  
  23. #include <ctype.h>
  24.  
  25. #include "as.h"
  26.  
  27. #include "obstack.h"        /* For "symbols.h" */
  28. #include "subsegs.h"
  29.  
  30. #ifndef WORKING_DOT_WORD
  31. extern int new_broken_words;
  32. #endif
  33.  
  34. /* symbol-name => struct symbol pointer */
  35. static struct hash_control *sy_hash;
  36.  
  37. /* Below are commented in "symbols.h". */
  38. symbolS *symbol_rootP;
  39. symbolS *symbol_lastP;
  40. symbolS abs_symbol;
  41.  
  42. #ifdef DEBUG_SYMS
  43. #define debug_verify_symchain verify_symbol_chain
  44. #else
  45. #define debug_verify_symchain (void)
  46. #endif
  47.  
  48. struct obstack notes;
  49.  
  50. static void fb_label_init PARAMS ((void));
  51.  
  52. /* symbol_new()
  53.   
  54.    Return a pointer to a new symbol.  Die if we can't make a new
  55.    symbol.  Fill in the symbol's values.  Add symbol to end of symbol
  56.    chain.
  57.  
  58.    This function should be called in the general case of creating a
  59.    symbol.  However, if the output file symbol table has already been
  60.    set, and you are certain that this symbol won't be wanted in the
  61.    output file, you can call symbol_create.  */
  62.  
  63. symbolS *
  64. symbol_new (name, segment, valu, frag)
  65.      const char *name;
  66.      segT segment;
  67.      valueT valu;
  68.      fragS *frag;
  69. {
  70.   symbolS *symbolP = symbol_create (name, segment, valu, frag);
  71.  
  72.   /*
  73.    * Link to end of symbol chain.
  74.    */
  75. #ifdef BFD_ASSEMBLER
  76.   {
  77.     extern int symbol_table_frozen;
  78.     if (symbol_table_frozen)
  79.       abort ();
  80.   }
  81. #endif
  82.   symbol_append (symbolP, symbol_lastP, &symbol_rootP, &symbol_lastP);
  83.   debug_verify_symchain (symbol_rootP, symbol_lastP);
  84.  
  85.   return symbolP;
  86. }
  87.  
  88. symbolS *
  89. symbol_create (name, segment, valu, frag)
  90.      const char *name;        /* It is copied, the caller can destroy/modify */
  91.      segT segment;        /* Segment identifier (SEG_<something>) */
  92.      valueT valu;        /* Symbol value */
  93.      fragS *frag;        /* Associated fragment */
  94. {
  95.   unsigned int name_length;
  96.   char *preserved_copy_of_name;
  97.   symbolS *symbolP;
  98.  
  99.   name_length = strlen (name) + 1;    /* +1 for \0 */
  100.   obstack_grow (¬es, name, name_length);
  101.   preserved_copy_of_name = obstack_finish (¬es);
  102. #ifdef STRIP_UNDERSCORE
  103.   if (preserved_copy_of_name[0] == '_')
  104.     preserved_copy_of_name++;
  105. #endif
  106.  
  107. #ifdef tc_canonicalize_symbol_name
  108.   preserved_copy_of_name =
  109.     tc_canonicalize_symbol_name (preserved_copy_of_name);
  110. #endif
  111.  
  112.   symbolP = (symbolS *) obstack_alloc (¬es, sizeof (symbolS));
  113.  
  114.   /* symbol must be born in some fixed state.  This seems as good as any. */
  115.   memset (symbolP, 0, sizeof (symbolS));
  116.  
  117. #ifdef BFD_ASSEMBLER
  118.   symbolP->bsym = bfd_make_empty_symbol (stdoutput);
  119.   assert (symbolP->bsym != 0);
  120.   symbolP->bsym->udata = (PTR) symbolP;
  121. #endif
  122.   S_SET_NAME (symbolP, preserved_copy_of_name);
  123.  
  124.   S_SET_SEGMENT (symbolP, segment);
  125.   S_SET_VALUE (symbolP, valu);
  126.   symbol_clear_list_pointers (symbolP);
  127.  
  128.   symbolP->sy_frag = frag;
  129. #ifndef BFD_ASSEMBLER
  130.   symbolP->sy_number = ~0;
  131.   symbolP->sy_name_offset = (unsigned int) ~0;
  132. #endif
  133.  
  134.   obj_symbol_new_hook (symbolP);
  135.  
  136. #ifdef tc_symbol_new_hook
  137.   tc_symbol_new_hook (symbolP);
  138. #endif
  139.  
  140.   return symbolP;
  141. }
  142.  
  143.  
  144. /*
  145.  *            colon()
  146.  *
  147.  * We have just seen "<name>:".
  148.  * Creates a struct symbol unless it already exists.
  149.  *
  150.  * Gripes if we are redefining a symbol incompatibly (and ignores it).
  151.  *
  152.  */
  153. void 
  154. colon (sym_name)        /* just seen "x:" - rattle symbols & frags */
  155.      register char *sym_name;    /* symbol name, as a cannonical string */
  156.      /* We copy this string: OK to alter later. */
  157. {
  158.   register symbolS *symbolP;    /* symbol we are working with */
  159.  
  160. #ifdef LOCAL_LABELS_DOLLAR
  161.   /* Sun local labels go out of scope whenever a non-local symbol is
  162.      defined.  */
  163.  
  164.   if (*sym_name != 'L')
  165.     dollar_label_clear ();
  166. #endif /* LOCAL_LABELS_DOLLAR */
  167.  
  168. #ifndef WORKING_DOT_WORD
  169.   if (new_broken_words)
  170.     {
  171.       struct broken_word *a;
  172.       int possible_bytes;
  173.       fragS *frag_tmp;
  174.       char *frag_opcode;
  175.  
  176.       extern const int md_short_jump_size;
  177.       extern const int md_long_jump_size;
  178.       possible_bytes = (md_short_jump_size
  179.             + new_broken_words * md_long_jump_size);
  180.  
  181.       frag_tmp = frag_now;
  182.       frag_opcode = frag_var (rs_broken_word,
  183.                   possible_bytes,
  184.                   possible_bytes,
  185.                   (relax_substateT) 0,
  186.                   (symbolS *) broken_words,
  187.                   0L,
  188.                   NULL);
  189.  
  190.       /* We want to store the pointer to where to insert the jump table in the
  191.      fr_opcode of the rs_broken_word frag.  This requires a little
  192.      hackery.  */
  193.       while (frag_tmp
  194.          && (frag_tmp->fr_type != rs_broken_word
  195.          || frag_tmp->fr_opcode))
  196.     frag_tmp = frag_tmp->fr_next;
  197.       know (frag_tmp);
  198.       frag_tmp->fr_opcode = frag_opcode;
  199.       new_broken_words = 0;
  200.  
  201.       for (a = broken_words; a && a->dispfrag == 0; a = a->next_broken_word)
  202.     a->dispfrag = frag_tmp;
  203.     }
  204. #endif /* WORKING_DOT_WORD */
  205.  
  206.   if ((symbolP = symbol_find (sym_name)) != 0)
  207.     {
  208. #ifdef RESOLVE_SYMBOL_REDEFINITION
  209.       if (RESOLVE_SYMBOL_REDEFINITION (symbolP))
  210.     return;
  211. #endif
  212.       /*
  213.        *    Now check for undefined symbols
  214.        */
  215.       if (!S_IS_DEFINED (symbolP))
  216.     {
  217.       if (S_GET_VALUE (symbolP) == 0)
  218.         {
  219.           symbolP->sy_frag = frag_now;
  220. #ifdef OBJ_VMS
  221.           S_GET_OTHER(symbolP) = const_flag;
  222. #endif
  223.           S_SET_VALUE (symbolP, (valueT) ((char*)obstack_next_free (&frags) - frag_now->fr_literal));
  224.           S_SET_SEGMENT (symbolP, now_seg);
  225. #ifdef N_UNDF
  226.           know (N_UNDF == 0);
  227. #endif /* if we have one, it better be zero. */
  228.  
  229.         }
  230.       else
  231.         {
  232.           /*
  233.            *    There are still several cases to check:
  234.            *        A .comm/.lcomm symbol being redefined as
  235.            *            initialized data is OK
  236.            *        A .comm/.lcomm symbol being redefined with
  237.            *            a larger size is also OK
  238.            *
  239.            * This only used to be allowed on VMS gas, but Sun cc
  240.            * on the sparc also depends on it.
  241.            */
  242.  
  243.           if (((!S_IS_DEBUG (symbolP)
  244.             && !S_IS_DEFINED (symbolP)
  245.             && S_IS_EXTERNAL (symbolP))
  246.            || S_GET_SEGMENT (symbolP) == bss_section)
  247.           && (now_seg == data_section
  248.               || now_seg == S_GET_SEGMENT (symbolP)))
  249.         {
  250.           /*
  251.            *    Select which of the 2 cases this is
  252.            */
  253.           if (now_seg != data_section)
  254.             {
  255.               /*
  256.                *   New .comm for prev .comm symbol.
  257.                *    If the new size is larger we just
  258.                *    change its value.  If the new size
  259.                *    is smaller, we ignore this symbol
  260.                */
  261.               if (S_GET_VALUE (symbolP)
  262.               < ((unsigned) frag_now_fix ()))
  263.             {
  264.               S_SET_VALUE (symbolP, (valueT) frag_now_fix ());
  265.             }
  266.             }
  267.           else
  268.             {
  269.               /* It is a .comm/.lcomm being converted to initialized
  270.              data.  */
  271.               symbolP->sy_frag = frag_now;
  272. #ifdef OBJ_VMS
  273.               S_GET_OTHER(symbolP) = const_flag;
  274. #endif /* OBJ_VMS */
  275.               S_SET_VALUE (symbolP, (valueT) frag_now_fix ());
  276.               S_SET_SEGMENT (symbolP, now_seg);    /* keep N_EXT bit */
  277.             }
  278.         }
  279.           else
  280.         {
  281. #if defined (S_GET_OTHER) && defined (S_GET_DESC)
  282.           as_fatal ("Symbol \"%s\" is already defined as \"%s\"/%d.%d.%ld.",
  283.                 sym_name,
  284.                 segment_name (S_GET_SEGMENT (symbolP)),
  285.                 S_GET_OTHER (symbolP), S_GET_DESC (symbolP),
  286.                 (long) S_GET_VALUE (symbolP));
  287. #else
  288.           as_fatal ("Symbol \"%s\" is already defined as \"%s\"/%ld.",
  289.                 sym_name,
  290.                 segment_name (S_GET_SEGMENT (symbolP)),
  291.                 (long) S_GET_VALUE (symbolP));
  292. #endif
  293.         }
  294.         }            /* if the undefined symbol has no value */
  295.     }
  296.       else
  297.     {
  298.       /* Don't blow up if the definition is the same */
  299.       if (!(frag_now == symbolP->sy_frag
  300.         && S_GET_VALUE (symbolP) == (char*)obstack_next_free (&frags) - frag_now->fr_literal
  301.         && S_GET_SEGMENT (symbolP) == now_seg))
  302.         as_fatal ("Symbol %s already defined.", sym_name);
  303.     }            /* if this symbol is not yet defined */
  304.  
  305.     }
  306.   else
  307.     {
  308.       symbolP = symbol_new (sym_name,
  309.                 now_seg,
  310.            (valueT) ((char*)obstack_next_free (&frags) - frag_now->fr_literal),
  311.                 frag_now);
  312. #ifdef OBJ_VMS
  313.       S_SET_OTHER (symbolP, const_flag);
  314. #endif /* OBJ_VMS */
  315.  
  316.       symbol_table_insert (symbolP);
  317.     }                /* if we have seen this symbol before */
  318.  
  319. #ifdef tc_frob_label
  320.   tc_frob_label (symbolP);
  321. #endif
  322. }
  323.  
  324.  
  325. /*
  326.  *            symbol_table_insert()
  327.  *
  328.  * Die if we can't insert the symbol.
  329.  *
  330.  */
  331.  
  332. void 
  333. symbol_table_insert (symbolP)
  334.      symbolS *symbolP;
  335. {
  336.   register const char *error_string;
  337.  
  338.   know (symbolP);
  339.   know (S_GET_NAME (symbolP));
  340.  
  341.   if ((error_string = hash_jam (sy_hash, S_GET_NAME (symbolP), (PTR) symbolP)))
  342.     {
  343.       as_fatal ("Inserting \"%s\" into symbol table failed: %s",
  344.         S_GET_NAME (symbolP), error_string);
  345.     }                /* on error */
  346. }                /* symbol_table_insert() */
  347.  
  348. /*
  349.  *            symbol_find_or_make()
  350.  *
  351.  * If a symbol name does not exist, create it as undefined, and insert
  352.  * it into the symbol table. Return a pointer to it.
  353.  */
  354. symbolS *
  355. symbol_find_or_make (name)
  356.      char *name;
  357. {
  358.   register symbolS *symbolP;
  359.  
  360.   symbolP = symbol_find (name);
  361.  
  362.   if (symbolP == NULL)
  363.     {
  364.       symbolP = symbol_make (name);
  365.  
  366.       symbol_table_insert (symbolP);
  367.     }                /* if symbol wasn't found */
  368.  
  369.   return (symbolP);
  370. }                /* symbol_find_or_make() */
  371.  
  372. symbolS *
  373. symbol_make (name)
  374.      CONST char *name;
  375. {
  376.   symbolS *symbolP;
  377.  
  378.   /* Let the machine description default it, e.g. for register names. */
  379.   symbolP = md_undefined_symbol ((char *) name);
  380.  
  381.   if (!symbolP)
  382.     symbolP = symbol_new (name, undefined_section, (valueT) 0, &zero_address_frag);
  383.  
  384.   return (symbolP);
  385. }                /* symbol_make() */
  386.  
  387. /*
  388.  *            symbol_find()
  389.  *
  390.  * Implement symbol table lookup.
  391.  * In:    A symbol's name as a string: '\0' can't be part of a symbol name.
  392.  * Out:    NULL if the name was not in the symbol table, else the address
  393.  *    of a struct symbol associated with that name.
  394.  */
  395.  
  396. symbolS *
  397. symbol_find (name)
  398.      CONST char *name;
  399. {
  400. #ifdef STRIP_UNDERSCORE
  401.   return (symbol_find_base (name, 1));
  402. #else /* STRIP_UNDERSCORE */
  403.   return (symbol_find_base (name, 0));
  404. #endif /* STRIP_UNDERSCORE */
  405. }                /* symbol_find() */
  406.  
  407. symbolS *
  408. symbol_find_base (name, strip_underscore)
  409.      CONST char *name;
  410.      int strip_underscore;
  411. {
  412.   if (strip_underscore && *name == '_')
  413.     name++;
  414.  
  415. #ifdef tc_canonicalize_symbol_name
  416.   {
  417.     char *copy;
  418.  
  419.     copy = (char *) alloca (strlen (name) + 1);
  420.     strcpy (copy, name);
  421.     name = tc_canonicalize_symbol_name (copy);
  422.   }
  423. #endif
  424.  
  425.   return ((symbolS *) hash_find (sy_hash, name));
  426. }
  427.  
  428. /*
  429.  * Once upon a time, symbols were kept in a singly linked list.  At
  430.  * least coff needs to be able to rearrange them from time to time, for
  431.  * which a doubly linked list is much more convenient.  Loic did these
  432.  * as macros which seemed dangerous to me so they're now functions.
  433.  * xoxorich.
  434.  */
  435.  
  436. /* Link symbol ADDME after symbol TARGET in the chain. */
  437. void 
  438. symbol_append (addme, target, rootPP, lastPP)
  439.      symbolS *addme;
  440.      symbolS *target;
  441.      symbolS **rootPP;
  442.      symbolS **lastPP;
  443. {
  444.   if (target == NULL)
  445.     {
  446.       know (*rootPP == NULL);
  447.       know (*lastPP == NULL);
  448.       *rootPP = addme;
  449.       *lastPP = addme;
  450.       return;
  451.     }                /* if the list is empty */
  452.  
  453.   if (target->sy_next != NULL)
  454.     {
  455. #ifdef SYMBOLS_NEED_BACKPOINTERS
  456.       target->sy_next->sy_previous = addme;
  457. #endif /* SYMBOLS_NEED_BACKPOINTERS */
  458.     }
  459.   else
  460.     {
  461.       know (*lastPP == target);
  462.       *lastPP = addme;
  463.     }                /* if we have a next */
  464.  
  465.   addme->sy_next = target->sy_next;
  466.   target->sy_next = addme;
  467.  
  468. #ifdef SYMBOLS_NEED_BACKPOINTERS
  469.   addme->sy_previous = target;
  470. #endif /* SYMBOLS_NEED_BACKPOINTERS */
  471. }
  472.  
  473. /* Set the chain pointers of SYMBOL to null. */
  474. void 
  475. symbol_clear_list_pointers (symbolP)
  476.      symbolS *symbolP;
  477. {
  478.   symbolP->sy_next = NULL;
  479. #ifdef SYMBOLS_NEED_BACKPOINTERS
  480.   symbolP->sy_previous = NULL;
  481. #endif
  482. }
  483.  
  484. #ifdef SYMBOLS_NEED_BACKPOINTERS
  485. /* Remove SYMBOLP from the list. */
  486. void 
  487. symbol_remove (symbolP, rootPP, lastPP)
  488.      symbolS *symbolP;
  489.      symbolS **rootPP;
  490.      symbolS **lastPP;
  491. {
  492.   if (symbolP == *rootPP)
  493.     {
  494.       *rootPP = symbolP->sy_next;
  495.     }                /* if it was the root */
  496.  
  497.   if (symbolP == *lastPP)
  498.     {
  499.       *lastPP = symbolP->sy_previous;
  500.     }                /* if it was the tail */
  501.  
  502.   if (symbolP->sy_next != NULL)
  503.     {
  504.       symbolP->sy_next->sy_previous = symbolP->sy_previous;
  505.     }                /* if not last */
  506.  
  507.   if (symbolP->sy_previous != NULL)
  508.     {
  509.       symbolP->sy_previous->sy_next = symbolP->sy_next;
  510.     }                /* if not first */
  511.  
  512.   debug_verify_symchain (*rootPP, *lastPP);
  513. }
  514.  
  515. /* Link symbol ADDME before symbol TARGET in the chain. */
  516. void 
  517. symbol_insert (addme, target, rootPP, lastPP)
  518.      symbolS *addme;
  519.      symbolS *target;
  520.      symbolS **rootPP;
  521.      symbolS **lastPP;
  522. {
  523.   if (target->sy_previous != NULL)
  524.     {
  525.       target->sy_previous->sy_next = addme;
  526.     }
  527.   else
  528.     {
  529.       know (*rootPP == target);
  530.       *rootPP = addme;
  531.     }                /* if not first */
  532.  
  533.   addme->sy_previous = target->sy_previous;
  534.   target->sy_previous = addme;
  535.   addme->sy_next = target;
  536.  
  537.   debug_verify_symchain (*rootPP, *lastPP);
  538. }
  539.  
  540. #endif /* SYMBOLS_NEED_BACKPOINTERS */
  541.  
  542. void 
  543. verify_symbol_chain (rootP, lastP)
  544.      symbolS *rootP;
  545.      symbolS *lastP;
  546. {
  547.   symbolS *symbolP = rootP;
  548.  
  549.   if (symbolP == NULL)
  550.     return;
  551.  
  552.   for (; symbol_next (symbolP) != NULL; symbolP = symbol_next (symbolP))
  553.     {
  554. #ifdef SYMBOLS_NEED_BACKPOINTERS
  555.       know (symbolP->sy_next->sy_previous == symbolP);
  556. #else
  557.       /* Walk the list anyways, to make sure pointers are still good.  */
  558.       ;
  559. #endif /* SYMBOLS_NEED_BACKPOINTERS */
  560.     }
  561.  
  562.   assert (lastP == symbolP);
  563. }
  564.  
  565. void
  566. verify_symbol_chain_2 (sym)
  567.      symbolS *sym;
  568. {
  569.   symbolS *p = sym, *n = sym;
  570. #ifdef SYMBOLS_NEED_BACKPOINTERS
  571.   while (symbol_previous (p))
  572.     p = symbol_previous (p);
  573. #endif
  574.   while (symbol_next (n))
  575.     n = symbol_next (n);
  576.   verify_symbol_chain (p, n);
  577. }
  578.  
  579. /* Resolve the value of a symbol.  This is called during the final
  580.    pass over the symbol table to resolve any symbols with complex
  581.    values.  */
  582.  
  583. void
  584. resolve_symbol_value (symp)
  585.      symbolS *symp;
  586. {
  587.   int resolved;
  588.  
  589.   if (symp->sy_resolved)
  590.     return;
  591.  
  592.   resolved = 0;
  593.  
  594.   if (symp->sy_resolving)
  595.     {
  596.       as_bad ("Symbol definition loop encountered at %s",
  597.           S_GET_NAME (symp));
  598.       S_SET_VALUE (symp, (valueT) 0);
  599.       resolved = 1;
  600.     }
  601.   else
  602.     {
  603.       offsetT left, right, val;
  604.       segT seg_left, seg_right;
  605.  
  606.       symp->sy_resolving = 1;
  607.  
  608.     reduce:
  609.       switch (symp->sy_value.X_op)
  610.     {
  611.     case O_absent:
  612.       S_SET_VALUE (symp, 0);
  613.       /* Fall through.  */
  614.     case O_constant:
  615.       S_SET_VALUE (symp, S_GET_VALUE (symp) + symp->sy_frag->fr_address);
  616.       if (S_GET_SEGMENT (symp) == expr_section)
  617.         S_SET_SEGMENT (symp, absolute_section);
  618.       resolved = 1;
  619.       break;
  620.  
  621.     case O_symbol:
  622.       resolve_symbol_value (symp->sy_value.X_add_symbol);
  623.  
  624. #if 0 /* I thought this was needed for some of the i386-svr4 PIC
  625.      support, but it appears I was wrong, and it breaks rs6000
  626.      support.  */
  627.       if (S_GET_SEGMENT (symp->sy_value.X_add_symbol) != undefined_section
  628.           && S_GET_SEGMENT (symp->sy_value.X_add_symbol) != expr_section)
  629. #endif
  630.         {
  631.           if (symp->sy_value.X_add_number == 0)
  632.         copy_symbol_attributes (symp, symp->sy_value.X_add_symbol);
  633.  
  634.           S_SET_VALUE (symp,
  635.                (symp->sy_value.X_add_number
  636.                 + symp->sy_frag->fr_address
  637.                 + S_GET_VALUE (symp->sy_value.X_add_symbol)));
  638.           if (S_GET_SEGMENT (symp) == expr_section
  639.           || S_GET_SEGMENT (symp) == undefined_section)
  640.         S_SET_SEGMENT (symp,
  641.                    S_GET_SEGMENT (symp->sy_value.X_add_symbol));
  642.         }
  643.       resolved = symp->sy_value.X_add_symbol->sy_resolved;
  644.       break;
  645.  
  646.     case O_uminus:
  647.     case O_bit_not:
  648.       resolve_symbol_value (symp->sy_value.X_add_symbol);
  649.       if (symp->sy_value.X_op == O_uminus)
  650.         val = - S_GET_VALUE (symp->sy_value.X_add_symbol);
  651.       else
  652.         val = ~ S_GET_VALUE (symp->sy_value.X_add_symbol);
  653.       S_SET_VALUE (symp,
  654.                (val
  655.             + symp->sy_value.X_add_number
  656.             + symp->sy_frag->fr_address));
  657.       if (S_GET_SEGMENT (symp) == expr_section
  658.           || S_GET_SEGMENT (symp) == undefined_section)
  659.         S_SET_SEGMENT (symp, absolute_section);
  660.       resolved = symp->sy_value.X_add_symbol->sy_resolved;
  661.       break;
  662.  
  663.     case O_add:
  664.       resolve_symbol_value (symp->sy_value.X_add_symbol);
  665.       resolve_symbol_value (symp->sy_value.X_op_symbol);
  666.       seg_left = S_GET_SEGMENT (symp->sy_value.X_add_symbol);
  667.       seg_right = S_GET_SEGMENT (symp->sy_value.X_op_symbol);
  668.       /* This case comes up with PIC support.  */
  669.       {
  670.         symbolS *s_left = symp->sy_value.X_add_symbol;
  671.         symbolS *s_right = symp->sy_value.X_op_symbol;
  672.  
  673.         if (seg_left == absolute_section)
  674.           {
  675.         symbolS *t;
  676.         segT ts;
  677.         t = s_left;
  678.         s_left = s_right;
  679.         s_right = t;
  680.         ts = seg_left;
  681.         seg_left = seg_right;
  682.         seg_right = ts;
  683.           }
  684.         if (seg_right == absolute_section
  685.         && s_right->sy_resolved)
  686.           {
  687.         symp->sy_value.X_add_number += S_GET_VALUE (s_right);
  688.         symp->sy_value.X_op_symbol = 0;
  689.         symp->sy_value.X_add_symbol = s_left;
  690.         symp->sy_value.X_op = O_symbol;
  691.         goto reduce;
  692.           }
  693.       }
  694.       /* fall through */
  695.  
  696.     case O_multiply:
  697.     case O_divide:
  698.     case O_modulus:
  699.     case O_left_shift:
  700.     case O_right_shift:
  701.     case O_bit_inclusive_or:
  702.     case O_bit_or_not:
  703.     case O_bit_exclusive_or:
  704.     case O_bit_and:
  705.     case O_subtract:
  706.       resolve_symbol_value (symp->sy_value.X_add_symbol);
  707.       resolve_symbol_value (symp->sy_value.X_op_symbol);
  708.       seg_left = S_GET_SEGMENT (symp->sy_value.X_add_symbol);
  709.       seg_right = S_GET_SEGMENT (symp->sy_value.X_op_symbol);
  710.       if (seg_left != seg_right
  711.           && seg_left != undefined_section
  712.           && seg_right != undefined_section)
  713.         as_bad ("%s is operation on symbols in different sections",
  714.             S_GET_NAME (symp));
  715.       if ((S_GET_SEGMENT (symp->sy_value.X_add_symbol)
  716.            != absolute_section)
  717.           && symp->sy_value.X_op != O_subtract)
  718.         as_bad ("%s is illegal operation on non-absolute symbols",
  719.             S_GET_NAME (symp));
  720.       left = S_GET_VALUE (symp->sy_value.X_add_symbol);
  721.       right = S_GET_VALUE (symp->sy_value.X_op_symbol);
  722.       switch (symp->sy_value.X_op)
  723.         {
  724.         case O_multiply:        val = left * right; break;
  725.         case O_divide:        val = left / right; break;
  726.         case O_modulus:        val = left % right; break;
  727.         case O_left_shift:        val = left << right; break;
  728.         case O_right_shift:        val = left >> right; break;
  729.         case O_bit_inclusive_or:    val = left | right; break;
  730.         case O_bit_or_not:        val = left |~ right; break;
  731.         case O_bit_exclusive_or:    val = left ^ right; break;
  732.         case O_bit_and:        val = left & right; break;
  733.         case O_add:            val = left + right; break;
  734.         case O_subtract:        val = left - right; break;
  735.         default:            abort ();
  736.         }
  737.       S_SET_VALUE (symp,
  738.                (symp->sy_value.X_add_number
  739.             + symp->sy_frag->fr_address
  740.             + val));
  741.       if (S_GET_SEGMENT (symp) == expr_section
  742.           || S_GET_SEGMENT (symp) == undefined_section)
  743.         S_SET_SEGMENT (symp, absolute_section);
  744.       resolved = (symp->sy_value.X_add_symbol->sy_resolved
  745.               && symp->sy_value.X_op_symbol->sy_resolved);
  746.          break;
  747.  
  748.     case O_register:
  749.     case O_big:
  750.     case O_illegal:
  751.       /* Give an error (below) if not in expr_section.  We don't
  752.          want to worry about expr_section symbols, because they
  753.          are fictional (they are created as part of expression
  754.          resolution), and any problems may not actually mean
  755.          anything.  */
  756.       break;
  757.     }
  758.     }
  759.  
  760.   /* Don't worry if we can't resolve an expr_section symbol.  */
  761.   if (resolved)
  762.     symp->sy_resolved = 1;
  763.   else if (S_GET_SEGMENT (symp) != expr_section)
  764.     {
  765.       as_bad ("can't resolve value for symbol \"%s\"", S_GET_NAME (symp));
  766.       symp->sy_resolved = 1;
  767.     }
  768. }
  769.  
  770. #ifdef LOCAL_LABELS_DOLLAR
  771.  
  772. /* Dollar labels look like a number followed by a dollar sign.  Eg, "42$".
  773.    They are *really* local.  That is, they go out of scope whenever we see a
  774.    label that isn't local.  Also, like fb labels, there can be multiple
  775.    instances of a dollar label.  Therefor, we name encode each instance with
  776.    the instance number, keep a list of defined symbols separate from the real
  777.    symbol table, and we treat these buggers as a sparse array.  */
  778.  
  779. static long *dollar_labels;
  780. static long *dollar_label_instances;
  781. static char *dollar_label_defines;
  782. static long dollar_label_count;
  783. static unsigned long dollar_label_max;
  784.  
  785. int 
  786. dollar_label_defined (label)
  787.      long label;
  788. {
  789.   long *i;
  790.  
  791.   know ((dollar_labels != NULL) || (dollar_label_count == 0));
  792.  
  793.   for (i = dollar_labels; i < dollar_labels + dollar_label_count; ++i)
  794.     if (*i == label)
  795.       return dollar_label_defines[i - dollar_labels];
  796.  
  797.   /* if we get here, label isn't defined */
  798.   return 0;
  799. }                /* dollar_label_defined() */
  800.  
  801. static int 
  802. dollar_label_instance (label)
  803.      long label;
  804. {
  805.   long *i;
  806.  
  807.   know ((dollar_labels != NULL) || (dollar_label_count == 0));
  808.  
  809.   for (i = dollar_labels; i < dollar_labels + dollar_label_count; ++i)
  810.     if (*i == label)
  811.       return (dollar_label_instances[i - dollar_labels]);
  812.  
  813.   /* If we get here, we haven't seen the label before, therefore its instance
  814.      count is zero.  */
  815.   return 0;
  816. }
  817.  
  818. void 
  819. dollar_label_clear ()
  820. {
  821.   memset (dollar_label_defines, '\0', (unsigned int) dollar_label_count);
  822. }
  823.  
  824. #define DOLLAR_LABEL_BUMP_BY 10
  825.  
  826. void 
  827. define_dollar_label (label)
  828.      long label;
  829. {
  830.   long *i;
  831.  
  832.   for (i = dollar_labels; i < dollar_labels + dollar_label_count; ++i)
  833.     if (*i == label)
  834.       {
  835.     ++dollar_label_instances[i - dollar_labels];
  836.     dollar_label_defines[i - dollar_labels] = 1;
  837.     return;
  838.       }
  839.  
  840.   /* if we get to here, we don't have label listed yet. */
  841.  
  842.   if (dollar_labels == NULL)
  843.     {
  844.       dollar_labels = (long *) xmalloc (DOLLAR_LABEL_BUMP_BY * sizeof (long));
  845.       dollar_label_instances = (long *) xmalloc (DOLLAR_LABEL_BUMP_BY * sizeof (long));
  846.       dollar_label_defines = xmalloc (DOLLAR_LABEL_BUMP_BY);
  847.       dollar_label_max = DOLLAR_LABEL_BUMP_BY;
  848.       dollar_label_count = 0;
  849.     }
  850.   else if (dollar_label_count == dollar_label_max)
  851.     {
  852.       dollar_label_max += DOLLAR_LABEL_BUMP_BY;
  853.       dollar_labels = (long *) xrealloc ((char *) dollar_labels,
  854.                      dollar_label_max * sizeof (long));
  855.       dollar_label_instances = (long *) xrealloc ((char *) dollar_label_instances,
  856.                       dollar_label_max * sizeof (long));
  857.       dollar_label_defines = xrealloc (dollar_label_defines, dollar_label_max);
  858.     }                /* if we needed to grow */
  859.  
  860.   dollar_labels[dollar_label_count] = label;
  861.   dollar_label_instances[dollar_label_count] = 1;
  862.   dollar_label_defines[dollar_label_count] = 1;
  863.   ++dollar_label_count;
  864. }
  865.  
  866. /*
  867.  *            dollar_label_name()
  868.  *
  869.  * Caller must copy returned name: we re-use the area for the next name.
  870.  *
  871.  * The mth occurence of label n: is turned into the symbol "Ln^Am"
  872.  * where n is the label number and m is the instance number. "L" makes
  873.  * it a label discarded unless debugging and "^A"('\1') ensures no
  874.  * ordinary symbol SHOULD get the same name as a local label
  875.  * symbol. The first "4:" is "L4^A1" - the m numbers begin at 1.
  876.  *
  877.  * fb labels get the same treatment, except that ^B is used in place of ^A.
  878.  */
  879.  
  880. char *                /* Return local label name. */
  881. dollar_label_name (n, augend)
  882.      register long n;        /* we just saw "n$:" : n a number */
  883.      register int augend;    /* 0 for current instance, 1 for new instance */
  884. {
  885.   long i;
  886.   /* Returned to caller, then copied.  used for created names ("4f") */
  887.   static char symbol_name_build[24];
  888.   register char *p;
  889.   register char *q;
  890.   char symbol_name_temporary[20];    /* build up a number, BACKWARDS */
  891.  
  892.   know (n >= 0);
  893.   know (augend == 0 || augend == 1);
  894.   p = symbol_name_build;
  895.   *p++ = 'L';
  896.  
  897.   /* Next code just does sprintf( {}, "%d", n); */
  898.   /* label number */
  899.   q = symbol_name_temporary;
  900.   for (*q++ = 0, i = n; i; ++q)
  901.     {
  902.       *q = i % 10 + '0';
  903.       i /= 10;
  904.     }
  905.   while ((*p = *--q) != '\0')
  906.     ++p;
  907.  
  908.   *p++ = 1;            /* ^A */
  909.  
  910.   /* instance number */
  911.   q = symbol_name_temporary;
  912.   for (*q++ = 0, i = dollar_label_instance (n) + augend; i; ++q)
  913.     {
  914.       *q = i % 10 + '0';
  915.       i /= 10;
  916.     }
  917.   while ((*p++ = *--q) != '\0');;
  918.  
  919.   /* The label, as a '\0' ended string, starts at symbol_name_build. */
  920.   return symbol_name_build;
  921. }
  922.  
  923. #endif /* LOCAL_LABELS_DOLLAR */
  924.  
  925. #ifdef LOCAL_LABELS_FB
  926.  
  927. /*
  928.  * Sombody else's idea of local labels. They are made by "n:" where n
  929.  * is any decimal digit. Refer to them with
  930.  *  "nb" for previous (backward) n:
  931.  *  or "nf" for next (forward) n:.
  932.  *
  933.  * We do a little better and let n be any number, not just a single digit, but
  934.  * since the other guy's assembler only does ten, we treat the first ten
  935.  * specially.
  936.  *
  937.  * Like someone else's assembler, we have one set of local label counters for
  938.  * entire assembly, not one set per (sub)segment like in most assemblers. This
  939.  * implies that one can refer to a label in another segment, and indeed some
  940.  * crufty compilers have done just that.
  941.  *
  942.  * Since there could be a LOT of these things, treat them as a sparse array.
  943.  */
  944.  
  945. #define FB_LABEL_SPECIAL (10)
  946.  
  947. static long fb_low_counter[FB_LABEL_SPECIAL];
  948. static long *fb_labels;
  949. static long *fb_label_instances;
  950. static long fb_label_count;
  951. static long fb_label_max;
  952.  
  953. /* this must be more than FB_LABEL_SPECIAL */
  954. #define FB_LABEL_BUMP_BY (FB_LABEL_SPECIAL + 6)
  955.  
  956. static void 
  957. fb_label_init ()
  958. {
  959.   memset ((void *) fb_low_counter, '\0', sizeof (fb_low_counter));
  960. }                /* fb_label_init() */
  961.  
  962. /* add one to the instance number of this fb label */
  963. void 
  964. fb_label_instance_inc (label)
  965.      long label;
  966. {
  967.   long *i;
  968.  
  969.   if (label < FB_LABEL_SPECIAL)
  970.     {
  971.       ++fb_low_counter[label];
  972.       return;
  973.     }
  974.  
  975.   if (fb_labels != NULL)
  976.     {
  977.       for (i = fb_labels + FB_LABEL_SPECIAL;
  978.        i < fb_labels + fb_label_count; ++i)
  979.     {
  980.       if (*i == label)
  981.         {
  982.           ++fb_label_instances[i - fb_labels];
  983.           return;
  984.         }            /* if we find it */
  985.     }            /* for each existing label */
  986.     }
  987.  
  988.   /* if we get to here, we don't have label listed yet. */
  989.  
  990.   if (fb_labels == NULL)
  991.     {
  992.       fb_labels = (long *) xmalloc (FB_LABEL_BUMP_BY * sizeof (long));
  993.       fb_label_instances = (long *) xmalloc (FB_LABEL_BUMP_BY * sizeof (long));
  994.       fb_label_max = FB_LABEL_BUMP_BY;
  995.       fb_label_count = FB_LABEL_SPECIAL;
  996.  
  997.     }
  998.   else if (fb_label_count == fb_label_max)
  999.     {
  1000.       fb_label_max += FB_LABEL_BUMP_BY;
  1001.       fb_labels = (long *) xrealloc ((char *) fb_labels,
  1002.                      fb_label_max * sizeof (long));
  1003.       fb_label_instances = (long *) xrealloc ((char *) fb_label_instances,
  1004.                           fb_label_max * sizeof (long));
  1005.     }                /* if we needed to grow */
  1006.  
  1007.   fb_labels[fb_label_count] = label;
  1008.   fb_label_instances[fb_label_count] = 1;
  1009.   ++fb_label_count;
  1010. }
  1011.  
  1012. static long 
  1013. fb_label_instance (label)
  1014.      long label;
  1015. {
  1016.   long *i;
  1017.  
  1018.   if (label < FB_LABEL_SPECIAL)
  1019.     {
  1020.       return (fb_low_counter[label]);
  1021.     }
  1022.  
  1023.   if (fb_labels != NULL)
  1024.     {
  1025.       for (i = fb_labels + FB_LABEL_SPECIAL;
  1026.        i < fb_labels + fb_label_count; ++i)
  1027.     {
  1028.       if (*i == label)
  1029.         {
  1030.           return (fb_label_instances[i - fb_labels]);
  1031.         }            /* if we find it */
  1032.     }            /* for each existing label */
  1033.     }
  1034.  
  1035.   /* We didn't find the label, so this must be a reference to the
  1036.      first instance.  */
  1037.   return 0;
  1038. }
  1039.  
  1040. /*
  1041.  *            fb_label_name()
  1042.  *
  1043.  * Caller must copy returned name: we re-use the area for the next name.
  1044.  *
  1045.  * The mth occurence of label n: is turned into the symbol "Ln^Bm"
  1046.  * where n is the label number and m is the instance number. "L" makes
  1047.  * it a label discarded unless debugging and "^B"('\2') ensures no
  1048.  * ordinary symbol SHOULD get the same name as a local label
  1049.  * symbol. The first "4:" is "L4^B1" - the m numbers begin at 1.
  1050.  *
  1051.  * dollar labels get the same treatment, except that ^A is used in place of ^B. */
  1052.  
  1053. char *                /* Return local label name. */
  1054. fb_label_name (n, augend)
  1055.      long n;            /* we just saw "n:", "nf" or "nb" : n a number */
  1056.      long augend;        /* 0 for nb, 1 for n:, nf */
  1057. {
  1058.   long i;
  1059.   /* Returned to caller, then copied.  used for created names ("4f") */
  1060.   static char symbol_name_build[24];
  1061.   register char *p;
  1062.   register char *q;
  1063.   char symbol_name_temporary[20];    /* build up a number, BACKWARDS */
  1064.  
  1065.   know (n >= 0);
  1066.   know (augend == 0 || augend == 1);
  1067.   p = symbol_name_build;
  1068.   *p++ = 'L';
  1069.  
  1070.   /* Next code just does sprintf( {}, "%d", n); */
  1071.   /* label number */
  1072.   q = symbol_name_temporary;
  1073.   for (*q++ = 0, i = n; i; ++q)
  1074.     {
  1075.       *q = i % 10 + '0';
  1076.       i /= 10;
  1077.     }
  1078.   while ((*p = *--q) != '\0')
  1079.     ++p;
  1080.  
  1081.   *p++ = 2;            /* ^B */
  1082.  
  1083.   /* instance number */
  1084.   q = symbol_name_temporary;
  1085.   for (*q++ = 0, i = fb_label_instance (n) + augend; i; ++q)
  1086.     {
  1087.       *q = i % 10 + '0';
  1088.       i /= 10;
  1089.     }
  1090.   while ((*p++ = *--q) != '\0');;
  1091.  
  1092.   /* The label, as a '\0' ended string, starts at symbol_name_build. */
  1093.   return (symbol_name_build);
  1094. }                /* fb_label_name() */
  1095.  
  1096. #endif /* LOCAL_LABELS_FB */
  1097.  
  1098.  
  1099. /*
  1100.  * decode name that may have been generated by foo_label_name() above.  If
  1101.  * the name wasn't generated by foo_label_name(), then return it unaltered.
  1102.  * This is used for error messages.
  1103.  */
  1104.  
  1105. char *
  1106. decode_local_label_name (s)
  1107.      char *s;
  1108. {
  1109.   char *p;
  1110.   char *symbol_decode;
  1111.   int label_number;
  1112.   int instance_number;
  1113.   char *type;
  1114.   const char *message_format = "\"%d\" (instance number %d of a %s label)";
  1115.  
  1116.   if (s[0] != 'L')
  1117.     return (s);
  1118.  
  1119.   for (label_number = 0, p = s + 1; isdigit (*p); ++p)
  1120.     {
  1121.       label_number = (10 * label_number) + *p - '0';
  1122.     }
  1123.  
  1124.   if (*p == 1)
  1125.     {
  1126.       type = "dollar";
  1127.     }
  1128.   else if (*p == 2)
  1129.     {
  1130.       type = "fb";
  1131.     }
  1132.   else
  1133.     {
  1134.       return (s);
  1135.     }
  1136.  
  1137.   for (instance_number = 0, p = s + 1; isdigit (*p); ++p)
  1138.     {
  1139.       instance_number = (10 * instance_number) + *p - '0';
  1140.     }
  1141.  
  1142.   symbol_decode = obstack_alloc (¬es, strlen (message_format) + 30);
  1143.   (void) sprintf (symbol_decode, message_format, label_number,
  1144.           instance_number, type);
  1145.  
  1146.   return (symbol_decode);
  1147. }                /* decode_local_label_name() */
  1148.  
  1149. /* Get the value of a symbol.  */
  1150.  
  1151. valueT
  1152. S_GET_VALUE (s)
  1153.      symbolS *s;
  1154. {
  1155.   if (!s->sy_resolved && !s->sy_resolving && s->sy_value.X_op != O_constant)
  1156.     resolve_symbol_value (s);
  1157.   if (s->sy_value.X_op != O_constant)
  1158.     as_bad ("Attempt to get value of unresolved symbol %s", S_GET_NAME (s));
  1159.   return (valueT) s->sy_value.X_add_number;
  1160. }
  1161.  
  1162. /* Set the value of a symbol.  */
  1163.  
  1164. void
  1165. S_SET_VALUE (s, val)
  1166.      symbolS *s;
  1167.      valueT val;
  1168. {
  1169.   s->sy_value.X_op = O_constant;
  1170.   s->sy_value.X_add_number = (offsetT) val;
  1171.   s->sy_value.X_unsigned = 0;
  1172. }
  1173.  
  1174. void
  1175. copy_symbol_attributes (dest, src)
  1176.      symbolS *dest, *src;
  1177. {
  1178. #ifdef BFD_ASSEMBLER
  1179.   /* In an expression, transfer the settings of these flags.
  1180.      The user can override later, of course.  */
  1181. #define COPIED_SYMFLAGS    (BSF_FUNCTION)
  1182.   dest->bsym->flags |= src->bsym->flags & COPIED_SYMFLAGS;
  1183. #endif
  1184.  
  1185. #ifdef OBJ_COPY_SYMBOL_ATTRIBUTES
  1186.   OBJ_COPY_SYMBOL_ATTRIBUTES (dest, src);
  1187. #endif
  1188. }
  1189.  
  1190. #ifdef BFD_ASSEMBLER
  1191.  
  1192. int
  1193. S_IS_EXTERNAL (s)
  1194.      symbolS *s;
  1195. {
  1196.   flagword flags = s->bsym->flags;
  1197.  
  1198.   /* sanity check */
  1199.   if (flags & BSF_LOCAL && flags & BSF_GLOBAL)
  1200.     abort ();
  1201.  
  1202.   return (flags & BSF_GLOBAL) != 0;
  1203. }
  1204.  
  1205. int
  1206. S_IS_COMMON (s)
  1207.      symbolS *s;
  1208. {
  1209.   return bfd_is_com_section (s->bsym->section);
  1210. }
  1211.  
  1212. int
  1213. S_IS_DEFINED (s)
  1214.      symbolS *s;
  1215. {
  1216.   return s->bsym->section != undefined_section;
  1217. }
  1218.  
  1219. int
  1220. S_IS_DEBUG (s)
  1221.      symbolS *s;
  1222. {
  1223.   if (s->bsym->flags & BSF_DEBUGGING)
  1224.     return 1;
  1225.   return 0;
  1226. }
  1227.  
  1228. int
  1229. S_IS_LOCAL (s)
  1230.      symbolS *s;
  1231. {
  1232.   flagword flags = s->bsym->flags;
  1233.  
  1234.   /* sanity check */
  1235.   if (flags & BSF_LOCAL && flags & BSF_GLOBAL)
  1236.     abort ();
  1237.  
  1238.   return (S_GET_NAME (s)
  1239.       && ! S_IS_DEBUG (s)
  1240.       && (strchr (S_GET_NAME (s), '\001')
  1241.           || strchr (S_GET_NAME (s), '\002')
  1242.           || (S_LOCAL_NAME (s)
  1243.           && !flag_keep_locals)));
  1244. }
  1245.  
  1246. int
  1247. S_IS_EXTERN (s)
  1248.      symbolS *s;
  1249. {
  1250.   return S_IS_EXTERNAL (s);
  1251. }
  1252.  
  1253. int
  1254. S_IS_STABD (s)
  1255.      symbolS *s;
  1256. {
  1257.   return S_GET_NAME (s) == 0;
  1258. }
  1259.  
  1260. CONST char *
  1261. S_GET_NAME (s)
  1262.      symbolS *s;
  1263. {
  1264.   return s->bsym->name;
  1265. }
  1266.  
  1267. segT
  1268. S_GET_SEGMENT (s)
  1269.      symbolS *s;
  1270. {
  1271.   return s->bsym->section;
  1272. }
  1273.  
  1274. void
  1275. S_SET_SEGMENT (s, seg)
  1276.      symbolS *s;
  1277.      segT seg;
  1278. {
  1279.   s->bsym->section = seg;
  1280. }
  1281.  
  1282. void
  1283. S_SET_EXTERNAL (s)
  1284.      symbolS *s;
  1285. {
  1286.   s->bsym->flags |= BSF_GLOBAL;
  1287.   s->bsym->flags &= ~(BSF_LOCAL|BSF_WEAK);
  1288. }
  1289.  
  1290. void
  1291. S_CLEAR_EXTERNAL (s)
  1292.      symbolS *s;
  1293. {
  1294.   s->bsym->flags |= BSF_LOCAL;
  1295.   s->bsym->flags &= ~(BSF_GLOBAL|BSF_WEAK);
  1296. }
  1297.  
  1298. void
  1299. S_SET_WEAK (s)
  1300.      symbolS *s;
  1301. {
  1302.   s->bsym->flags |= BSF_WEAK;
  1303.   s->bsym->flags &= ~(BSF_GLOBAL|BSF_LOCAL);
  1304. }
  1305.  
  1306. void
  1307. S_SET_NAME (s, name)
  1308.      symbolS *s;
  1309.      char *name;
  1310. {
  1311.   s->bsym->name = name;
  1312. }
  1313. #endif /* BFD_ASSEMBLER */
  1314.  
  1315. void
  1316. symbol_begin ()
  1317. {
  1318.   symbol_lastP = NULL;
  1319.   symbol_rootP = NULL;        /* In case we have 0 symbols (!!) */
  1320.   sy_hash = hash_new ();
  1321.  
  1322.   memset ((char *) (&abs_symbol), '\0', sizeof (abs_symbol));
  1323. #ifdef BFD_ASSEMBLER
  1324. #if defined (EMIT_SECTION_SYMBOLS) || !defined (RELOC_REQUIRES_SYMBOL)
  1325.   abs_symbol.bsym = bfd_abs_section.symbol;
  1326. #endif
  1327. #else
  1328.   /* Can't initialise a union. Sigh. */
  1329.   S_SET_SEGMENT (&abs_symbol, absolute_section);
  1330. #endif
  1331.   abs_symbol.sy_value.X_op = O_constant;
  1332.  
  1333. #ifdef LOCAL_LABELS_FB
  1334.   fb_label_init ();
  1335. #endif /* LOCAL_LABELS_FB */
  1336. }
  1337.  
  1338.  
  1339. int indent_level;
  1340.  
  1341. static void
  1342. indent ()
  1343. {
  1344.   printf ("%*s", indent_level * 4, "");
  1345. }
  1346.  
  1347. void print_expr_1 PARAMS ((FILE *, expressionS *));
  1348. void print_symbol_value_1 PARAMS ((FILE *, symbolS *));
  1349.  
  1350. void
  1351. print_symbol_value_1 (file, sym)
  1352.      FILE *file;
  1353.      symbolS *sym;
  1354. {
  1355.   const char *name = S_GET_NAME (sym);
  1356.   if (!name || !name[0])
  1357.     name = "(unnamed)";
  1358.   fprintf (file, "sym %lx %s", sym, name);
  1359.   if (sym->sy_frag != &zero_address_frag)
  1360.     fprintf (file, " frag %lx", (long) sym->sy_frag);
  1361.   if (sym->written)
  1362.     fprintf (file, " written");
  1363.   if (sym->sy_resolved)
  1364.     fprintf (file, " resolved");
  1365.   else if (sym->sy_resolving)
  1366.     fprintf (file, " resolving");
  1367.   if (sym->sy_used_in_reloc)
  1368.     fprintf (file, " used-in-reloc");
  1369.   if (sym->sy_used)
  1370.     fprintf (file, " used");
  1371.   if (S_IS_LOCAL (sym))
  1372.     fprintf (file, " local");
  1373.   if (S_IS_EXTERN (sym))
  1374.     fprintf (file, " extern");
  1375.   if (S_IS_DEBUG (sym))
  1376.     fprintf (file, " debug");
  1377.   if (S_IS_DEFINED (sym))
  1378.     fprintf (file, " defined");
  1379.   fprintf (file, " %s", segment_name (S_GET_SEGMENT (sym)));
  1380.   if (sym->sy_resolved)
  1381.     {
  1382.       segT s = S_GET_SEGMENT (sym);
  1383.  
  1384.       if (s != undefined_section
  1385.           && s != expr_section)
  1386.     fprintf (file, " %lx", (long) S_GET_VALUE (sym));
  1387.     }
  1388.   else if (indent_level < 8 && S_GET_SEGMENT (sym) != undefined_section)
  1389.     {
  1390.       indent_level++;
  1391.       fprintf (file, "\n%*s<", indent_level * 4, "");
  1392.       print_expr_1 (file, &sym->sy_value);
  1393.       fprintf (file, ">");
  1394.       indent_level--;
  1395.     }
  1396.   fflush (file);
  1397. }
  1398.  
  1399. void
  1400. print_symbol_value (sym)
  1401.      symbolS *sym;
  1402. {
  1403.   indent_level = 0;
  1404.   print_symbol_value_1 (stderr, sym);
  1405.   fprintf (stderr, "\n");
  1406. }
  1407.  
  1408. void
  1409. print_expr_1 (file, exp)
  1410.      FILE *file;
  1411.      expressionS *exp;
  1412. {
  1413.   fprintf (file, "expr %lx ", (long) exp);
  1414.   switch (exp->X_op)
  1415.     {
  1416.     case O_illegal:
  1417.       fprintf (file, "illegal");
  1418.       break;
  1419.     case O_absent:
  1420.       fprintf (file, "absent");
  1421.       break;
  1422.     case O_constant:
  1423.       fprintf (file, "constant %lx", (long) exp->X_add_number);
  1424.       break;
  1425.     case O_symbol:
  1426.       indent_level++;
  1427.       fprintf (file, "symbol\n%*s<", indent_level * 4, "");
  1428.       print_symbol_value_1 (file, exp->X_add_symbol);
  1429.       fprintf (file, ">");
  1430.     maybe_print_addnum:
  1431.       if (exp->X_add_number)
  1432.     fprintf (file, "\n%*s%lx", indent_level * 4, "",
  1433.          (long) exp->X_add_number);
  1434.       indent_level--;
  1435.       break;
  1436.     case O_register:
  1437.       fprintf (file, "register #%d", (int) exp->X_add_number);
  1438.       break;
  1439.     case O_big:
  1440.       fprintf (file, "big");
  1441.       break;
  1442.     case O_uminus:
  1443.       fprintf (file, "uminus -<");
  1444.       indent_level++;
  1445.       print_symbol_value_1 (file, exp->X_add_symbol);
  1446.       fprintf (file, ">");
  1447.       goto maybe_print_addnum;
  1448.     case O_bit_not:
  1449.       fprintf (file, "bit_not");
  1450.       break;
  1451.     case O_multiply:
  1452.       fprintf (file, "multiply");
  1453.       break;
  1454.     case O_divide:
  1455.       fprintf (file, "divide");
  1456.       break;
  1457.     case O_modulus:
  1458.       fprintf (file, "modulus");
  1459.       break;
  1460.     case O_left_shift:
  1461.       fprintf (file, "lshift");
  1462.       break;
  1463.     case O_right_shift:
  1464.       fprintf (file, "rshift");
  1465.       break;
  1466.     case O_bit_inclusive_or:
  1467.       fprintf (file, "bit_ior");
  1468.       break;
  1469.     case O_bit_exclusive_or:
  1470.       fprintf (file, "bit_xor");
  1471.       break;
  1472.     case O_bit_and:
  1473.       fprintf (file, "bit_and");
  1474.       break;
  1475.     case O_add:
  1476.       indent_level++;
  1477.       fprintf (file, "add\n%*s<", indent_level * 4, "");
  1478.       print_symbol_value_1 (file, exp->X_add_symbol);
  1479.       fprintf (file, ">\n%*s<", indent_level * 4, "");
  1480.       print_symbol_value_1 (file, exp->X_op_symbol);
  1481.       fprintf (file, ">");
  1482.       goto maybe_print_addnum;
  1483.     case O_subtract:
  1484.       indent_level++;
  1485.       fprintf (file, "subtract\n%*s<", indent_level * 4, "");
  1486.       print_symbol_value_1 (file, exp->X_add_symbol);
  1487.       fprintf (file, ">\n%*s<", indent_level * 4, "");
  1488.       print_symbol_value_1 (file, exp->X_op_symbol);
  1489.       fprintf (file, ">");
  1490.       goto maybe_print_addnum;
  1491.     default:
  1492.       fprintf (file, "{unknown opcode %d}", (int) exp->X_op);
  1493.       break;
  1494.     }
  1495.   fflush (stdout);
  1496. }
  1497.  
  1498. void
  1499. print_expr (exp)
  1500.      expressionS *exp;
  1501. {
  1502.   print_expr_1 (stderr, exp);
  1503.   fprintf (stderr, "\n");
  1504. }
  1505.  
  1506. /* end of symbols.c */
  1507.